package raft

import (
	"errors"
	"fmt"

	"hundsun.com/hsl/hschain/protos"
	"hundsun.com/hsl/hschain/protos/common"
)

// ConsensusType 共识类型
const ConsensusType = "raft"

// Validate ...
func (b *ConsensusConfigPayload) Validate() error {
	if b.MinerCount%2 == 0 {
		return errors.New("'minerCount'  of consensus config  must be an odd number")
	}

	if b.MinerCount == 1 {
		return errors.New("'minerCount'  of consensus config  must be greater than or equal to 3")
	}

	if len(b.DefaultMiners) != int(b.MinerCount) {
		return fmt.Errorf("size of DefaultMiners must be %d", b.MinerCount)
	}

	for _, m := range b.DefaultMiners {
		err := m.Validate()
		if err != nil {
			return err
		}
	}

	minerAddrMap := make(map[string]bool)
	for _, m := range b.DefaultMiners {
		if minerAddrMap[m.Address] {
			return fmt.Errorf("duplicated miner '%s'", m.Address)
		}
		minerAddrMap[m.Address] = true
	}

	minerNetAddrMap := make(map[string]bool)
	for _, m := range b.DefaultMiners {
		peerID := m.PeerID
		if minerNetAddrMap[peerID] {
			return fmt.Errorf("duplicated miner network peerID '%s'", peerID)
		}
		minerNetAddrMap[peerID] = true
	}

	return nil
}

// Validate miner Validate
func (m *Miner) Validate() error {
	err := (protos.Address(m.Address)).Validate()
	if err != nil {
		return err
	}
	if m.PeerID == "" {
		return errors.New("network address cannot be empty")
	}
	return common.ValidatePeerID(m.PeerID)
}
